<template>
  <div class="advanced-chat-container">
    <TransitionGroup name="message-fade" tag="div" class="messages-wrapper" @scroll.passive="handleScroll">
      <div v-for="(msg, index) in messages" :key="msg.id" :class="['message-item', msg.role]">
        <!-- 用户消息 -->
        <div v-if="msg.role === 'user'" class="message-bubble user">
          {{ msg.content }}
          <div>
            <span class="timestamp">{{ formatTime(msg.createdAt) }}</span>
          </div>
        </div>
        <!-- AI消息 -->
        <div v-else class="message-ai">
          <div class="thinking-logo-wrapper">
            <img :src="logo" />
          </div>
          <!-- 深度思考提示 -->
          <div v-if="msg.thinking" class="thinking-area">
            <div class="thinking-quote">
              <span class="thinking-label">🧠 已深度思考（用时 {{ msg.thinkingTime }} 秒）</span>
              <div class="thinking-content">{{ msg.thinkingContent }}</div>
            </div>
          </div>
          <!-- 正式回答 -->
          <div class="message-bubble ai">
            <div class="markdown-content" v-html="renderMarkdown(msg.content)"></div>
            <div v-if="msg.status === 'streaming'" class="streaming-cursor"></div>
            <div class="status-footer">
              <span class="timestamp">{{ formatTime(msg.updatedAt) }}</span>
              <span v-if="msg.status === 'error'" class="retry-btn" @click="retryMessage(msg)"> ⟳ 重试 </span>
            </div>
          </div>
        </div>
      </div>
      <!-- 加载指示器 -->
      <div v-if="loading" class="loading-indicator">
        <div class="spinner"></div>
        <span>正在生成回答...</span>
      </div>
    </TransitionGroup>
    <!-- 增强输入区域 -->
    <div class="enhanced-input-area">
      <div class="input-wrapper">
        <textarea
          ref="inputEl"
          v-model="inputText"
          :disabled="loading"
          @keydown.enter.exact.prevent="sendMessage"
          @keydown.shift.enter.exact="handleShiftEnter"
          placeholder="输入消息（Enter发送，Shift+Enter换行）"
          rows="1"
          autocomplete="off"
          spellcheck="false"
        ></textarea>
        <button class="send-btn" :class="{ loading }" @click="sendMessage" :disabled="!canSend || loading">
          <span v-if="!loading">发送</span>
          <div v-else class="sending-spinner">
            <span @click.stop="abortRequest" :disabled="!isStreaming">停止</span>
          </div>
        </button>
      </div>
      <div class="input-footer">
        <span class="char-count">{{ inputText.length }}/1000</span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, nextTick, onMounted } from 'vue'
import MarkdownIt from 'markdown-it'
import logo from '@/assets/logo.png'
import hljs from 'highlight.js'
import 'highlight.js/styles/atom-one-dark.css'
import 'highlight.js/lib/common'

// Markdown配置（带代码高亮）
const md = new MarkdownIt({
  html: true,
  linkify: true,
  highlight: (str, lang) => {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return `<pre class="hljs"><code>${
          hljs.highlight(str, {
            language: lang,
            ignoreIllegals: true
          }).value
        }</code></pre>`
      } catch (__) {}
    }
    return `<pre class="hljs"><code>${md.utils.escapeHtml(str)}</code></pre>`
  }
})

// 响应式数据
const messages = reactive([])
const inputText = ref('')
const loading = ref(false)
const inputEl = ref(null)
const autoScroll = ref(true)
const isStreaming = ref(false)
const abortController = ref(null)
// 保存消息容器的引用
const messagesContainer = ref(null)

// 计算属性
const canSend = computed(() => {
  return inputText.value.trim().length > 0 && !loading.value && inputText.value.length <= 1000
})

// 格式化时间
const formatTime = date => {
  return new Date(date).toLocaleTimeString('zh-CN', {
    hour: '2-digit',
    minute: '2-digit'
  })
}

// Markdown渲染方法
const renderMarkdown = content => {
  return md.render(content)
}

const processStream = async reader => {
  const decoder = new TextDecoder('utf-8')
  let buffer = ''
  const currentMsg = messages[messages.length - 1] // 当前消息对象
  // 启动计时器
  if (!currentMsg.thinkingTimer) {
    currentMsg.thinkingTime = 0
    currentMsg.thinkingTimer = setInterval(() => {
      currentMsg.thinkingTime++
    }, 1000)
  }
  try {
    while (true) {
      const { done, value } = await reader.read()
      if (done) {
        currentMsg.status = 'completed'
        break
      }
      buffer += decoder.decode(value, { stream: true })
      while (buffer.includes('\n')) {
        const lineEnd = buffer.indexOf('\n')
        const line = buffer.slice(0, lineEnd).trim()
        buffer = buffer.slice(lineEnd + 1)
        if (line.startsWith('data: ')) {
          const payload = line.replace('data: ', '')
          if (payload === '[DONE]') {
            currentMsg.status = 'completed'
            break
          }
          try {
            const parsed = JSON.parse(payload)
            if (parsed.choices && parsed.choices[0].delta) {
              const delta = parsed.choices[0].delta
              if (delta.reasoning_content) {
                currentMsg.thinkingContent += delta.reasoning_content
                currentMsg.thinking = true
              }
              if (delta.content) {
                currentMsg.content += delta.content
              }
              currentMsg.updatedAt = Date.now()
              if (parsed.choices[0].finish_reason === 'stop') {
                currentMsg.status = 'completed'
                break
              }
            }
          } catch (error) {
            console.error('JSON 解析错误:', error)
            currentMsg.status = 'error'
            currentMsg.content += '\n（数据解析错误）'
          }
        }
      }
      await nextTick()
      if (autoScroll.value) {
        scrollToBottom()
      }
    }
  } catch (error) {
    console.error('流处理错误:', error)
    currentMsg.status = 'error'
    currentMsg.content += '\n（好的，已停下）'
  } finally {
    // 清除计时器
    if (currentMsg.thinkingTimer) {
      clearInterval(currentMsg.thinkingTimer)
      currentMsg.thinkingTimer = null
    }
    loading.value = false
    isStreaming.value = false
  }
}

// 滚动控制
const scrollToBottom = () => {
  if (messagesContainer.value) {
    messagesContainer.value.scrollTo({
      top: messagesContainer.value.scrollHeight,
      behavior: 'smooth'
    })
  }
}

// 自动滚动条件判断
const handleScroll = e => {
  const { scrollTop, scrollHeight, clientHeight } = e.target
  autoScroll.value = scrollHeight - (scrollTop + clientHeight) < 50
}

// 发送消息
const sendMessage = async () => {
  if (!canSend.value) return
  const userMessage = {
    id: Date.now(),
    role: 'user',
    content: inputText.value.trim(),
    createdAt: Date.now()
  }
  const aiMessage = {
    id: Date.now() + 1,
    role: 'assistant',
    content: '',
    thinking: false,
    thinkingContent: '',
    thinkingTime: 0,
    thinkingTimer: null, // 新增
    status: 'streaming',
    createdAt: Date.now(),
    updatedAt: Date.now()
  }
  messages.push(userMessage, aiMessage)
  inputText.value = ''
  loading.value = true
  autoScroll.value = true
  isStreaming.value = true
  abortController.value = new AbortController()
  try {
    const response = await fetch('https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer token123-456`
      },
      body: JSON.stringify({
        model: 'deepseek-r1',
        messages: messages.slice(0, -1).map(msg => ({
          role: msg.role,
          content: msg.content
        })),
        max_tokens: 4096,
        temperature: 0.1,
        stream: true
      }),
      signal: abortController.value.signal // 传递 AbortSignal
    })
    if (!response.ok) throw new Error(`HTTP错误 ${response.status}`)
    await processStream(response.body.getReader())
  } catch (error) {
    if (error.name === 'AbortError') {
      console.log('请求已中止')
      aiMessage.status = 'aborted'
      aiMessage.content += '\n 好的，已停下。'
    } else {
      console.error('请求失败:', error)
      aiMessage.status = 'error'
      aiMessage.content = '请求失败: ' + error.message
    }
  } finally {
    loading.value = false
    isStreaming.value = false
    abortController.value = null
  }
}

// 中断请求
const abortRequest = () => {
  if (abortController.value) {
    abortController.value.abort()
    isStreaming.value = false
  }
}

// 其他交互逻辑
const handleShiftEnter = () => {
  inputText.value += '\n'
  autoResizeTextarea()
}

const autoResizeTextarea = () => {
  nextTick(() => {
    const textarea = inputEl.value
    textarea.style.height = 'auto'
    textarea.style.height = `${textarea.scrollHeight}px`
  })
}

const retryMessage = msg => {
  const index = messages.indexOf(msg)
  if (index !== -1) {
    messages.splice(index, 1)
    inputText.value = messages[index - 1].content
    sendMessage()
  }
}

// 生命周期钩子
onMounted(() => {
  autoResizeTextarea()
  scrollToBottom()
})
</script>

<style lang="scss" scoped>
.advanced-chat-container {
  max-width: 1200px;
  margin: 0 auto;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #f8f9fa;
}

.messages-wrapper {
  flex: 1;
  overflow-y: auto;
  padding: 20px;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
  }

  &::-webkit-scrollbar-thumb {
    background: #888;
    border-radius: 4px;
  }
}

.message-item {
  display: flex;
  margin: 18px 0;
  font-size: 15px;
  align-items: flex-end;

  &.user {
    justify-content: flex-end;
  }

  &.assistant {
    justify-content: flex-start;
  }
}

// 用户消息
.message-bubble.user {
  background: #eff6ff;
  border-radius: 16px;
  padding: 12px 18px;
  font-size: 16px;
  line-height: 26px;
  max-width: 70%;
  min-width: 120px;
  word-break: break-word;

  .timestamp {
    display: block;
    text-align: right;
    font-size: 13px;
    margin-top: 10px;
  }
}

// AI消息
.message-ai {
  display: flex;
  flex-direction: column;
  max-width: 90%;
  width: auto;

  + .message-item.user {
    margin-top: 32px;
  }

  .thinking-logo-wrapper {
    width: 24px;
    height: 24px;

    img {
      width: 100%;
      height: 100%;
    }
  }
}

// 思考区域
.thinking-area {
  width: 100%;
  margin-bottom: 18px;
  padding: 0;
  background: none;
}

.thinking-quote {
  display: flex;
  flex-direction: column;
  background: #f8f9fa;
  border-left: 2px solid #d3d3d3;
  padding: 18px 0 18px 22px;
  color: #888;
  font-size: 15px;
  line-height: 1.8;
}

.thinking-label {
  font-size: 14px;
  color: #b0b4ba;
  margin-bottom: 8px;
  font-weight: 500;
  display: flex;
  align-items: center;

  &::before {
    content: '🧠';
    margin-right: 6px;
    font-size: 16px;
  }
}

.thinking-content {
  color: #8b8b8b;
  font-size: 15px;
  line-height: 1.8;
  white-space: pre-wrap;
}

// AI内容区域
.ai-content {
  background: #f8f9fa;
  border-radius: 12px;
  padding: 16px 20px;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  width: 100%;
  border: 1px solid #e9ecef;

  .markdown-content {
    :deep(p) {
      margin: 0 0 8px 0;
      &:last-child {
        margin-bottom: 0;
      }
    }

    :deep(pre) {
      background: #f1f3f4;
      border: 1px solid #dadce0;
      padding: 8px 12px;
      border-radius: 6px;
      overflow-x: auto;
      margin: 8px 0;
      font-size: 13px;
    }

    :deep(code) {
      font-family: 'Consolas', 'Monaco', monospace;
      font-size: 0.9em;
    }
  }

  .streaming-cursor {
    display: inline-block;
    width: 8px;
    height: 1em;
    background: #666;
    margin-left: 4px;
    animation: blink 1s infinite;
  }
}

.status-footer {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  margin-top: 8px;
  font-size: 11px;
  color: #999;

  .timestamp {
    color: #999;
  }

  .retry-btn {
    margin-left: 8px;
    color: #007bff;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;

    &:hover {
      background: rgba(0, 123, 255, 0.1);
      text-decoration: underline;
    }
  }
}

// 输入区域
.enhanced-input-area {
  background: white;
  padding: 16px;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.05);

  .input-wrapper {
    display: flex;
    gap: 12px;
    align-items: flex-end;

    textarea {
      flex: 1;
      min-height: 48px;
      max-height: 200px;
      padding: 12px;
      border: 1px solid #ddd;
      border-radius: 8px;
      resize: none;
      font-family: inherit;
      line-height: 1.5;

      &:focus {
        border-color: #007bff;
        outline: none;
        box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2);
      }
    }

    .send-btn {
      height: 48px;
      width: 80px;
      border: none;
      border-radius: 8px;
      background: #007bff;
      color: white;
      cursor: pointer;
      transition: all 0.2s;

      &:disabled {
        background: #ccc;
        cursor: not-allowed;
      }

      &.loading {
        background: #007bffaa;
      }
    }
  }

  .input-footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 8px;
    font-size: 0.9em;

    .char-count {
      color: #999;
    }
  }
}

// 加载指示器
.loading-indicator {
  display: flex;
  align-items: center;
  font-size: 12px;
  gap: 8px;
  color: #666;
  padding: 12px 0;

  .spinner {
    width: 12px;
    height: 12px;
    border: 2px solid #ddd;
    border-top-color: #007bff;
    border-radius: 50%;
    animation: spin 1s linear infinite;
  }
}

// 动画
@keyframes blink {
  50% {
    opacity: 0;
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

// 过渡动画
.message-fade-enter-active,
.message-fade-leave-active {
  transition: all 0.3s ease;
}

.message-fade-enter-from,
.message-fade-leave-to {
  opacity: 0;
  transform: translateY(10px);
}
</style>
